// 当然，以下是这些Go语言注释的中文翻译：
// 
// ```go
// 版权所有 2012 The Go 项目作者。保留所有权利。
// 使用该源代码受以BSD风格许可条款的约束，
// 该许可条款可在LICENSE文件中找到。
// ```
// md5:a2b8441cca608eb8

package osext

import (
	"syscall"
	"unicode/utf16"
	"unsafe"
)

var (
	kernel                = syscall.MustLoadDLL("kernel32.dll")
	getModuleFileNameProc = kernel.MustFindProc("GetModuleFileNameW")
)

// 当然，以下是Go语言注释的中文翻译：
// 
// ```go
// 当 hModule 为 NULL 时调用 GetModuleFileName()
// ```
// 
// 这个注释说明了代码中调用了 `GetModuleFileName()` 函数，并且传入的 `hModule` 参数为 `NULL`。在Windows API中，当 `hModule` 设置为 `NULL` 时，`GetModuleFileName` 函数会返回当前进程的可执行文件的完整路径。 md5:7946ff7f0377b3cd
func executable() (exePath string, err error) {
	return getModuleFileName()
}

func getModuleFileName() (string, error) {
	var n uint32
	b := make([]uint16, syscall.MAX_PATH)
	size := uint32(len(b))

	r0, _, e1 := getModuleFileNameProc.Call(0, uintptr(unsafe.Pointer(&b[0])), uintptr(size))
	n = uint32(r0)
	if n == 0 {
		return "", e1
	}
	return string(utf16.Decode(b[0:n])), nil
}
